pub mod image;

use cairo::{Context, ImageSurface};

use crate::image::Image;

use clap::{App, Arg};

pub type Node = (f64, f64);

pub enum GtkUpdate {
    UpdateLabel(String),
    UpdateImage(Image),
}

pub fn init_matches<'a>() -> clap::ArgMatches<'a> {
    App::new("Tsp-viewer")
        .version("0.1.0")
        .about("tsp 的 GTK 包装")
        .arg(
            Arg::with_name("pn")
                .long("pn")
                .value_name("INT")
                .default_value("30")
                .help("生态群系大小")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("pm")
                .long("pm")
                .value_name("DOUBLE")
                .default_value("0.1")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("pc")
                .long("pc")
                .value_name("DOUBLE")
                .default_value("0.8")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("debug")
                .long("debug")
                .value_name("DEBUG LEVEL")
                .help("WARN/INFO/DEBUG/TRACE")
                .default_value("WARN")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("data")
                .help("你想要计算的图")
                .index(1)
                .default_value("data.in"),
        )
        .get_matches()
}

pub fn draw_initial() -> Image {
    let mut image = Image::new();

    image.with_surface(|surface| {
        let cr = Context::new(surface);
        cr.set_source_rgb(1., 1., 1.);
        cr.paint();
    });

    image
}

pub fn draw_square(cr: &Context, start: &Node, w: f64, h: f64) {
    let (x, y) = *start;

    cr.set_source_rgb(0., 0., 0.);
    cr.rectangle(x, y, w, h);
    cr.stroke();
}

pub fn draw_line(cr: &Context, start: Node, end: Node) {
    let (from_x, from_y) = start;
    let (end_x, end_y) = end;

    cr.set_source_rgb(0., 0., 0.);
    cr.move_to(from_x, from_y);
    cr.line_to(end_x, end_y);
    cr.stroke();
}

pub fn draw_image_if_dirty(
    cr: &Context,
    image: &ImageSurface,
    origin: (i32, i32),
    dimensions: (i32, i32),
) {
    let x = origin.0 as f64;
    let y = origin.1 as f64;
    let w = dimensions.0 as f64;
    let h = dimensions.1 as f64;
    let (clip_x1, clip_y1, clip_x2, clip_y2) = cr.clip_extents();
    if clip_x1 >= x + w || clip_y1 >= y + h || clip_x2 <= x || clip_y2 <= y {
        return;
    }
    cr.set_source_surface(image, x, y);
    cr.paint();

    cr.set_source_rgba(0.0, 0.0, 0.0, 0.0);
}
